package _5_proxy.jdkproxy;

import lombok.extern.slf4j.Slf4j;
import sun.misc.ProxyGenerator;

import java.io.FileOutputStream;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;

/**
 * @author bpzj 2019/12/11 11:35
 */
@Slf4j
public class UseJdkProxy {

    public static void main(String[] args) {

        // ITarget: 被代理接口
        // Target:  被代理类 (接口的一个实现)
        ITarget target = new Target();

        // InvocationHandler 就是具体的、对  **被代理类的某些方法**  进行增强的 代码
        // 此处的代码，没有对  被代理类的 method  进行区分处理，也就是： 增强了被代理类的所有方法
        ClassLoader classLoader = Target.class.getClassLoader();
        Class<?>[] interfaces = Target.class.getInterfaces();
        ITarget proxy =  (ITarget) Proxy.newProxyInstance(classLoader, interfaces, new EnhanceHandler(target));
        // proxyInstance.sing();
        proxy.targetMethod();

        // 注意上面的 InvocationHandler

        log.info("输出动态代理类的信息");
        Class<?> aClass = proxy.getClass();
        Method[] methods = aClass.getDeclaredMethods();
        for (Method method : methods) {
            log.info("生成的动态代理类, 有方法: " + method.getName());
        }

        // 使用 ProxyGenerator 保存 生成动态代理类的 .class 信息
        byte[] classFile = ProxyGenerator.generateProxyClass("com.sun.proxy.$Proxy0", Target.class.getInterfaces(), Modifier.PUBLIC);
        String path = "proxyClass.class";
        try(FileOutputStream fos = new FileOutputStream(path)) {
            fos.write(classFile);
            fos.flush();
            log.info("代理类class文件写入成功");
        } catch (Exception e) {
            log.info("写文件错误");
        }
    }
}
